﻿using System;
using System.Collections.Generic;
using System.Text;

using System.IO;
using System.Reflection;
namespace BiaoQianPrint.Tools
{
    //有两种写法，平时使用 二进制的写法。
    //开发时：如果需要改变类的结构。 那么就调用第二种。写成txt。
    //然后手动增加一列，然后再写入二进制格式的。
    public static class FileDbManager
    {
        #region  泛型  反射。  把list写入二进制文件。
        /// <summary>
        /// 读取信息方法
        /// </summary>
        /// <returns>读取是否成功</returns>
        public static List<T> ReadDataFromBFile<T>(string pFilePath)
        {
            List<T> listObj = new List<T>();
            FileStream fs;
            if (!File.Exists(pFilePath))
            {
                //Console.WriteLine("\n\t读取失败！\n错误原因：可能不存在此文件");
                return listObj;
            }
            fs = new FileStream(pFilePath, FileMode.Open);
            BinaryReader br = new BinaryReader(fs);
            listObj.Clear();

            //从磁盘上读取信息
            try
            {
                br.BaseStream.Seek(0, SeekOrigin.Begin); //将文件指针设置到文件开始



                while (br.BaseStream.Position < br.BaseStream.Length) // 当未到达文件结尾时｛｝
                {
                    Type tt = typeof(T);
                    //System.Type tt = System.Type.GetType();//获取指定名称的类型  参数是  "类的完全限定名"
                    object obj = Activator.CreateInstance(tt, null);//创建指定类型实例
                    PropertyInfo[] fields = obj.GetType().GetProperties();//获取指定对象的所有公共属性
                    foreach (PropertyInfo t in fields)
                    {
                        //string s = t.PropertyType.ToString();
                        //string s = t.GetType().ToString();
                        if (t.PropertyType == typeof(int))
                            t.SetValue(obj, br.ReadInt32(), null);//给对象赋值
                        else if (t.PropertyType == typeof(string))
                            t.SetValue(obj, br.ReadString(), null);
                        else if (t.PropertyType==typeof(FilePathType))
                            t.SetValue(obj,br.ReadByte(),null);
                    }

                    listObj.Add((T)obj);
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("出错！ 读取结束！错误描述："+ex.Message);
            }
            br.Close();
            fs.Close();

            return listObj;
        }
        #endregion

        #region #region  泛型  反射。  读取二进制文件到List。
        /// <summary>
        /// 写入信息方法
        /// </summary>
        /// <returns>写入是否成功</returns>
        public static void SaveDataToBFile<T>(List<T> listObj, string pFilePath)
        {

            FileStream fs;
            if (File.Exists(pFilePath))
            {
                File.Delete(pFilePath);
            }
            fs = new FileStream(pFilePath, FileMode.Create);

            //数据保存到磁盘中
            BinaryWriter bw = new BinaryWriter(fs);
            foreach (T item in listObj)
            {
                Type t = item.GetType();//获得该类的Type
                foreach (PropertyInfo pi in t.GetProperties())
                {
                    object value1 = pi.GetValue(item, null);//获得 当前属性的值
                    string name = pi.Name;//获得当前属性的名字
                    //获得当前属性的类型,
                    if (value1.GetType() == typeof(int))
                    {
                        bw.Write((int)value1);
                    }
                    else if (value1.GetType() == typeof(string))
                    {
                        bw.Write((string)value1);
                    }
                }
                bw.Flush();
            }
            bw.Close();
            fs.Close();
            Console.WriteLine("保存成功!");
        }

        #endregion

        #region 旧的读txt文件的方法
        //从txt读取数据
        public static List<T> ReadData<T>(string pFilePath)
        {
            List<T> listObj = new List<T>();
            if (!File.Exists(pFilePath))
            {
                return listObj;
            }

            StreamReader sr = new StreamReader(pFilePath, Encoding.UTF8);
            String line = "";
            while ((line = sr.ReadLine()) != null)
            {
                string[] lineSplit = line.Split('#');

                Type tt = typeof(T);
                T obj = (T)Activator.CreateInstance(tt, null);//创建指定类型实例
                PropertyInfo[] fields = obj.GetType().GetProperties();//获取指定对象的所有公共属性

                int i=0;
                foreach (PropertyInfo t in fields)
                {
                    //string s = t.PropertyType.ToString();
                    //string s = t.GetType().ToString();
                    if (t.PropertyType == typeof(int))
                        t.SetValue(obj, CommonClass.GetIntFromString(lineSplit[i]), null);//给对象赋值
                    else if (t.PropertyType == typeof(string))
                        t.SetValue(obj, lineSplit[i], null);
                    else if (t.PropertyType == typeof(FilePathType))
                        t.SetValue(obj, Convert.ToByte(lineSplit[i]), null);

                    i++;
                }

                listObj.Add(obj);
            }
            sr.Close();
            return listObj;
        }

        #endregion
        #region     //向txt写回数据  暂时没有功能，直接在txt中手工维护。
        public static void SaveData<T>(List<T> listObj, string pFilePath)
        {
            //如果文件存在，就删除文件
            if (File.Exists(pFilePath))
            {
                File.Delete(pFilePath);
            }

            //如果不存在，他会自己创建的。
            FileStream fw = new FileStream(pFilePath, FileMode.Create, FileAccess.Write);//创建写入文件 
            StreamWriter sw = new StreamWriter(fw, Encoding.UTF8);

            foreach (T item in listObj)
            {
                StringBuilder sb = new StringBuilder();
                //sb.Append(item.mAuthID + "#");//项目编号string
                //sb.Append(item.mAuthName + "#");//项目名称string
                //sb.Append(item.mFID); //密钥名称 string 
                

                Type t = item.GetType();//获得该类的Type
                foreach (PropertyInfo pi in t.GetProperties())
                {
                    object value1 = pi.GetValue(item, null);//获得 当前属性的值
                    string name = pi.Name;//获得当前属性的名字
                    //获得当前属性的类型,
                    if (value1.GetType() == typeof(int))
                    {
                        sb.Append(value1.ToString() + "#");
                        
                    }
                    else if (value1.GetType() == typeof(string))
                    {
                        sb.Append(value1 + "#");
                    }
                    else if (value1.GetType() == typeof(FilePathType))
                    {
                        //sb.Append((FilePathType)value1 + "#");
                        //sb.Append((FilePathType)Enum.Parse(typeof(FilePathType), value1.ToString())+"#");
                        sb.Append(Convert.ToString((byte)(FilePathType)value1)+"#");
                    }
                }
                sw.WriteLine(sb.Remove(sb.Length-1,1));//  去掉最后一个#
            }
            sw.Close();
            fw.Close();
        }
       
        #endregion
    }
}
